/*
 * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AF_COMMON_H
#define AF_COMMON_H

#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include "pthread.h"
#include "ot_type.h"
#include "ot_af_common.h"
#include "ss_scene_detection.h"
#include "ss_pdaf.h"
#include "ss_cdaf.h"
#include "ss_daaf.h"
#include "ss_af_manager.h"
#include "ss_log.h"

#define ZOOM_MIN (1.0)
#define F_NUM_BASE (1.6)
#define ZOOM_MAX (30.0)
#define ZOOM_STEP (0.1)
#define ENABLE_AFPROC 1
#define FLOAT_EPSILON (1e-6)
#define MIN_ISO (100)
#define MIN_MOVE_PERCENT (0.01)
#define MAX_MOVE_PERCENT (1.0)
#define MAX_PARALLEL_SEARCH_STEP_SIZE (100)
#define MAX_FINE_SEARCH_STEP_SIZE (50)
#define MIN_FIXED_WINDOW_WIDTH_NUM (4)
#define MIN_FIXED_WINDOW_HEIGHT_NUM (5)
#define MAX_WAIT_AFTER_FOCUS_CNT (50)
#define MAX_DEFOCUS_STABLE_THRESHOLD (50)
#define MAX_STABLE_FILTER_LEN (20)

#define CHECK_FAILED_RET(ret, target, retCode, fmt...) \
    do {                                               \
        if ((ret) != (target)) {                       \
            OT_LOG_ERR(MODULE_NAME_AF, fmt);           \
            return retCode;                            \
        }                                              \
    } while (0)

#define CHECK_FAILED_RET_VOID(ret, target, fmt...) \
    do {                                           \
        if ((ret) != (target)) {                   \
            OT_LOG_ERR(MODULE_NAME_AF, fmt);       \
            return;                                \
        }                                          \
    } while (0)

#define CHECK_NULL_RET(val, retCode, fmt...) \
    do {                                     \
        if ((val) == NULL) {                 \
            OT_LOG_ERR(MODULE_NAME_AF, fmt); \
            return retCode;                  \
        }                                    \
    } while (0)

#define CHECK_NULL_UNLOCK_RET(mutex, val, retCode, fmt...) \
    do {                                                   \
        if ((val) == NULL) {                               \
            OT_LOG_ERR(MODULE_NAME_AF, fmt);               \
            pthread_mutex_unlock(mutex);                   \
            return retCode;                                \
        }                                                  \
    } while (0)

#define CHECK_NULL_RET_VOID(val, fmt...)     \
    do {                                     \
        if ((val) == NULL) {                 \
            OT_LOG_ERR(MODULE_NAME_AF, fmt); \
            return;                          \
        }                                    \
    } while (0)

#define CHECK_NULL_PRINT(val, fmt...)        \
    do {                                     \
        if ((val) == NULL) {                 \
            OT_LOG_ERR(MODULE_NAME_AF, fmt); \
        }                                    \
    } while (0)

#define CHECK_NULL_GOTO(val, gotoBranch, fmt...) \
    do {                                         \
        if ((val) == NULL) {                     \
            OT_LOG_ERR(MODULE_NAME_AF, fmt);     \
            goto gotoBranch;                     \
        }                                        \
    } while (0)

/* 搜索范围 search 信息 */
typedef struct {
    td_s32 curCode;
    td_s32 nearEnd; /* Nearest position lens can move to */
    td_s32 farEnd;  /* Farest position lens can move to  */
} OT_AF_MonitorFocusSearchInfo;

typedef struct {
    td_bool isChanged;
    OT_AF_ZoomInfo zoomInfo;
} OT_AF_ZoomTrackingInfo;

typedef struct {
    td_bool isValid;
    OT_AF_SceneDetectionResult sceneDetectionResults;
} OT_AF_MonitorSceneDetectionInfo;

typedef struct {
    td_bool isValid;
    OT_AF_CDAF_FvInfoResult fvInfoResults;
} OT_AF_MonitorCDAFInfo;

typedef struct {
    td_bool isValid;
    OT_PDAF_Results pdafResults;
} OT_AF_MonitorPDAFInfo;

typedef struct {
    td_bool isValid;
    OT_AF_DAAF_DepthInfoDesc daafResults;
} OT_AF_MonitorDAAFInfo;

typedef struct {
    OT_AF_WindowConfig windowConfig;
    OT_AF_MonitorPDAFInfo pdafInfo;
    OT_AF_MonitorDAAFInfo daafInfo;
    OT_AF_ZoomTrackingInfo zoomTrackingInfo;
    OT_AF_OpticsInfo opticsInfo;
    OT_AF_MonitorFocusSearchInfo focusSearchInfo;
    OT_AF_MonitorSceneDetectionInfo sceneDetectionInfo;
    td_bool forceFocusFlag;
    td_bool setFocusWinFlag;
    td_u64 pdProcessssKpi;
    OT_AF_MonitorCDAFInfo cdafInfo;
    td_bool unLockFocusFlag;
} OT_AF_MonitorInfo;

typedef struct {
    OT_AF_FocusWindow focusWindow;
} OT_AF_InFocusPolicyInfo;

typedef struct {
    td_s64 timestamp;
    td_float pdValue;
    td_u32 pdConfidence;
    td_s32 defocus;
} OT_AF_PDAFPolicyInfo;

typedef struct {
    td_s64 timestamp;
    td_s32 stepCode;
    td_u32 focusValue;
} OT_AF_CDAFPolicyInfo;

typedef struct {
    td_s64 timestamp;
    td_s32 distanceInMilliMeters; /* Calculated object distance (in millimeters). */
    td_s32 confidence;            /* Confidence of measured distance. */
} OT_AF_DAAFPolicyInfo;

typedef enum {
    OT_AF_FOCUS_POLICY_FAILED = -1, /* focus failed */
    OT_AF_FOCUS_POLICY_IN_FOCUS,    /* in focus */
    OT_AF_FOCUS_POLICY_PDAF,
    OT_AF_FOCUS_POLICY_CDAF,
    OT_AF_FOCUS_POLICY_DAAF,
    OT_AF_FOCUS_POLICY_ZOOM_TRACKING,
    OT_AF_FOCUS_POLICY_MAX = 0x7FFFFFFF /* Type Max */
} OT_AF_FocusPolicyType;

typedef struct {
    OT_AF_FocusPolicyType focusPolicy;
    union {
        OT_AF_InFocusPolicyInfo inFocusPolicyInfo;
        OT_AF_PDAFPolicyInfo pdafPolicyInfo;
        OT_AF_CDAFPolicyInfo cdafPolicyInfo;
        OT_AF_DAAFPolicyInfo daafPolicyInfo;
        OT_AF_ZoomTrackingInfo zoomTrackingInfo;
    } info;
    OT_AF_FocusWindow focusedWindow;
} OT_AF_FocusPolicyInfo;

typedef enum {
    OT_AF_COMMON_MSG_PDAF = 0,
    OT_AF_COMMON_MSG_CDAF,
    OT_AF_COMMON_MSG_DAAF,
    OT_AF_COMMON_MSG_ZOOM_TRACKING,
    OT_AF_COMMON_MSG_BUTT
} OT_AF_COMMON_MsgType;

typedef struct {
    OT_AF_COMMON_MsgType type;
    td_u32 msgLen;
    td_u32 msgId;
} OT_AF_COMMON_MsgHead;

typedef struct {
    OT_AF_COMMON_MsgHead head;
    OT_AF_ZoomInfo zoomInfo;
    OT_AF_PDAFPolicyInfo pdafPolicyInfo;
} OT_AF_COMMON_MsgPdaf;

typedef struct {
    OT_AF_COMMON_MsgHead head;
    OT_AF_ZoomInfo zoomInfo;
    OT_AF_CDAFPolicyInfo cdafPolicyInfo;
} OT_AF_COMMON_MsgCdaf;

typedef struct {
    OT_AF_COMMON_MsgHead head;
    OT_AF_ZoomInfo zoomInfo;
    OT_AF_DAAFPolicyInfo daafPolicyInfo;
} OT_AF_COMMON_MsgDaaf;

typedef struct {
    OT_AF_COMMON_MsgHead head;
    OT_AF_ZoomTrackingInfo zoomTrackingInfo;
} OT_AF_COMMON_MsgZoom;

typedef struct {
    OT_AF_COMMON_MsgType type;
    td_u32 msgLen;
    td_u32 msgId;
    td_s32 retCode;
} OT_AF_COMMON_AckHead;

typedef struct {
    td_void *context;
    td_s32 (*reply)(td_void *context, OT_AF_COMMON_AckHead *ack);
} OT_AF_COMMON_ReplyCallback;

typedef struct {
    td_void *context;
    td_s32 (*sendMsg)(td_void *handle, const OT_AF_COMMON_MsgHead *msg, OT_AF_COMMON_AckHead *ack);
    td_s32 (*postMsg)(td_void *handle, const OT_AF_COMMON_MsgHead *msg);
    td_s32 (*registerReplyCb)(td_void *handle, OT_AF_COMMON_ReplyCallback *cb);
} OT_AF_COMMON_PadFunc;

typedef enum {
    MONOTONIC_INCREASE,
    MONOTONIC_DECREASE,
} Monotonicity;

td_s32 FindValidMotorRange(const OT_AF_TuningFocusSearchLimitsTable *focusSearchLimitsTable,
                           const OT_AF_ZoomInfo *zoomInfo, OT_AF_TuningFocusSearchLimits *range);

td_s32 GetValidTargetCode(td_s32 curCode, td_s32 targetCode, OT_AF_TuningFocusSearchLimits *range);

td_s32 GetSmoothControlDefocus(const OT_AF_TuningFocusSmoothCtrlTable *focusSmoothCtrlTable,
                               const OT_AF_ZoomInfo *zoomInfo, td_s32 defocus);

td_u64 GetCurrentTimeMS(td_void);

td_u64 GetCurSysPTS(td_void);

td_s32 DistanceToLensPosition(td_s32 distmm);

td_bool IsMonotonicInt(td_s32 *numsInt, td_u32 numsSize);

td_bool IsMonotonicFloat(td_float *numsFloat, td_u32 numsSize);

td_bool FloatNumEqual(td_float a, td_float b);

td_u32 GetPdConfThreshold(const OT_AF_TuningPDConfTable *pdConfTable, const OT_AF_OpticsInfo *opticsInfo);

td_s32 UpdatePdFocusConvergeTuningData(const OT_AF_TuningPDFocusConvergeTable *focusConvergeTable,
                                       OT_AF_TuningPDFocusConverge *pdFocusConverge, const OT_AF_ZoomInfo *zoomInfo,
                                       const OT_AF_OpticsInfo *opticsInfo);

td_s32 UpdateExhibitModeTuningData(const OT_AF_TuningExhibitModeTable *exhibitModeTable,
                                   OT_AF_TuningExhibitMode *exhibitMode, const OT_AF_ZoomInfo *zoomInfo,
                                   const OT_AF_OpticsInfo *opticsInfo);

#endif /* AF_COMMON_H */
